package gui;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.concurrent.ExecutionException;

import javax.swing.*;

import montecarlomultithread.MonteCarloConcurrent;
import montecarlosinglethread.MonteCarlo;


public class GUIMonteCarlo {

	private static void createAndShowGUI(int width, int height)
			throws NumberFormatException, IOException {
		JFrame frame = new JFrame("MonteCarlo Algorithm");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(width, height);

		// Initialization of the panel
		JPanel mainPanel = new JPanel();
		mainPanel.setLayout(new GridLayout(0, 2));

		/*************** variables, JLabel and other components ***********************/
		Object[][] tmpTab = readFile();
		Object[] parameters = new Object[6];
		int i = 0;


		/***************** adding to panel *********************************************/

		// Single or Multithreaded
		String[] SingleMultiTable = new String[2];
		SingleMultiTable[0] = "Single Thread";
		SingleMultiTable[1] = "Multi Threads";
		final JComboBox SingleMultiList = new JComboBox(SingleMultiTable);
		JLabel SingleMultiLabel = new JLabel("Which version do you want to use ? ");
		mainPanel.add(SingleMultiLabel);
		mainPanel.add(SingleMultiList);

		// Call/Put
		String[] callputTable = new String[2];
		callputTable[0] = "Call";
		callputTable[1] = "Put";
		final JComboBox CallPutList = new JComboBox(callputTable);
		JLabel CallPutLabel = new JLabel("Is the action a call or a put ? ");
		mainPanel.add(CallPutLabel);
		mainPanel.add(CallPutList);

		// retrieving S from file
		i = 0;
		while (i < parameters.length) {
			parameters[i] = tmpTab[0][i];
			i++;
		}
		final JComboBox STable = new JComboBox(parameters);
		JLabel SLabel = new JLabel("Current price of the option's underlying asset : ");
		mainPanel.add(SLabel);
		mainPanel.add(STable);

		// retrieving X from file
		i = 0;
		while (i < parameters.length) {
			parameters[i] = tmpTab[1][i];
			i++;
		}
		final JComboBox XTable = new JComboBox(parameters);
		JLabel XLabel = new JLabel("Strike price of the option : ");
		mainPanel.add(XLabel);
		mainPanel.add(XTable);

		// retrieving T from file
		i = 0;
		while (i < parameters.length) {
			parameters[i] = tmpTab[2][i];
			i++;
		}
		final JComboBox TTable = new JComboBox(parameters);
		JLabel TLabel = new JLabel("Time to maturity of the option : ");
		mainPanel.add(TLabel);
		mainPanel.add(TTable);

		// retrieving r from file
		i = 0;
		while (i < parameters.length) {
			parameters[i] = tmpTab[3][i];
			i++;
		}
		final JComboBox rTable = new JComboBox(parameters);
		JLabel rLabel = new JLabel("Discount rate : ");
		mainPanel.add(rLabel);
		mainPanel.add(rTable);

		// retrieving b from file
		i = 0;
		while (i < parameters.length) {
			parameters[i] = tmpTab[4][i];
			i++;
		}
		final JComboBox bTable = new JComboBox(parameters);
		JLabel bLabel = new JLabel("Cost of carry rate : ");
		mainPanel.add(bLabel);
		mainPanel.add(bTable);

		// retrieving v from file
		i = 0;
		while (i < parameters.length) {
			parameters[i] = tmpTab[5][i];
			i++;
		}
		final JComboBox vTable = new JComboBox(parameters);
		JLabel vLabel = new JLabel("Volatility of the underlying asset : ");
		mainPanel.add(vLabel);
		mainPanel.add(vTable);

		// retrieving nSteps from file
		i = 0;
		while (i < parameters.length) {
			parameters[i] = tmpTab[6][i];
			i++;
		}
		final JComboBox nStepsTable = new JComboBox(parameters);
		JLabel nStepsLabel = new JLabel(
				"Number of steps to execute for each option price path : ");
		mainPanel.add(nStepsLabel);
		mainPanel.add(nStepsTable);

		// retrieving nSimulations from file
		i = 0;
		while (i < parameters.length) {
			parameters[i] = tmpTab[7][i];
			i++;
		}
		final JComboBox nSimulationsTable = new JComboBox(parameters);
		JLabel nSimulationsLabel = new JLabel("Number of simulations to run : ");
		mainPanel.add(nSimulationsLabel);
		mainPanel.add(nSimulationsTable);

		// Calculate button
		JButton calculateButton = new JButton("Run MonteCarlo");
		mainPanel.add(calculateButton);

		// Result label
		final JLabel resultLabel = new JLabel("The result will be displayed here once you clicked on \"Run MonteCarlo\".");
		mainPanel.add(resultLabel);

		
		
		/************************** Action listener ******************************************/
		
		// Action on calculateButton
		calculateButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
				double resultTable[] = new double[2]; // will contain the result and the time spend at computing the value 
				
				/************ Case of Single and Multi Thread ***************/

				if(SingleMultiList.getSelectedItem() == "Single Thread") // If single thread is selected
				{
					resultTable = MonteCarlo.main(
							CallPutList.getSelectedItem().toString(),
							new Double (STable.getSelectedItem().toString()), new Double (XTable.getSelectedItem().toString()),
							new Double (TTable.getSelectedItem().toString()), new Double (rTable.getSelectedItem().toString()),
							new Double (bTable.getSelectedItem().toString()), new Double (vTable.getSelectedItem().toString()),
							new Integer (nStepsTable.getSelectedItem().toString()),
							new Integer (nSimulationsTable.getSelectedItem().toString()));
					//System.out.println("je suis dans le if");
				}
				
				else if(SingleMultiList.getSelectedItem() == "Multi Threads") // If single thread is selected
				{
					try {
						resultTable = MonteCarloConcurrent.main(
								CallPutList.getSelectedItem().toString(),
								new Double (STable.getSelectedItem().toString()), new Double (XTable.getSelectedItem().toString()),
								new Double (TTable.getSelectedItem().toString()), new Double (rTable.getSelectedItem().toString()),
								new Double (bTable.getSelectedItem().toString()), new Double (vTable.getSelectedItem().toString()),
								new Integer (nStepsTable.getSelectedItem().toString()),
								new Integer (nSimulationsTable.getSelectedItem().toString()));
						//System.out.println("je suis dans le else if");
					} catch (NumberFormatException e1) {
						e1.printStackTrace();
					} catch (InterruptedException e1) {
						e1.printStackTrace();
					} catch (ExecutionException e1) {
						e1.printStackTrace();
					}
				}
				
				else 
					{
					//System.out.println("je suis dans le else");
					resultLabel.setText("Problem in the passing of the thread argument.");
					}
				
				resultLabel.setText("<html>The result is : " + resultTable[0] + ".<br>Computation of the value took " + resultTable[1] + " seconds.</html>");
					
			}
		});
		
		

		frame.getContentPane().add(mainPanel);
		// frame.pack();
		frame.setVisible(true);
	}

	private static Object[][] readFile() throws NumberFormatException,
			IOException {

		Object[][] testValuesTab = new Object[8][6]; // 8 parameters, 6 sets
		BufferedReader reader = new BufferedReader(new FileReader(
				"testValues.txt"));

		String parametersLine = null;
		String[] parametersTable = null;
		int nbLine = 0;

		// Put everything from the text file into testValuesTab, with the
		// correct parsing
		while ((parametersLine = reader.readLine()) != null) {

			parametersTable = parametersLine.split(",");

			for (int i = 0; i < parametersTable.length; i++) {

				if (nbLine == 6 || nbLine == 7) {
					testValuesTab[nbLine][i] = Integer
							.parseInt(parametersTable[i]);
				} else if (nbLine == 0 || nbLine == 1 || nbLine == 2
						|| nbLine == 3 || nbLine == 4 || nbLine == 5)
					testValuesTab[nbLine][i] = Double
							.parseDouble(parametersTable[i]);
				else
					System.out.println("Error in the txt file.");
			}

			nbLine++;
		}

		reader.close();

		return testValuesTab;
	}

	public static void main(String[] args) {
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				try {
					createAndShowGUI(900, 600);
				} catch (NumberFormatException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		});
	}
}
